﻿using System;
using System.Text;
using AopAlliance.Intercept;
using Landpy.CruiseControlNet.Infrastructure.Aop.DependencyInjection;
using Landpy.CruiseControlNet.Infrastructure.Aop.WrapAttribute;

namespace Landpy.CruiseControlNet.Infrastructure.Aop.Interceptor
{
    /// <summary>
    /// Log Exception Interceptor,associate with the attriubte：
    /// <see cref="LogExceptionAttribute"/>
    /// <example> The code example is as following:
    /// <code>
    /// class ThrowExceptionAopTest : IAopTest
    /// {
    ///     [LogException]
    ///     [ExceptionMessageBox]
    ///     [NotThrowException]
    ///     public bool TestBoolean()
    ///     {
    ///         throw new NotImplementedException("The ThrowExceptionAopTest TestBoolean Method");
    ///     }
    /// }
    /// </code>
    /// </example>
    /// </summary>
    public class LogExceptionInterceptor : IMethodInterceptor
    {
        /// <summary>
        /// The interface implement for DI.
        /// </summary>
        public ILog Log { set; private get; }

        /// <summary>
        /// The method DI logic.
        /// </summary>
        /// <param name="invocation">The original method context.</param>
        /// <returns>The original method return value.</returns>
        public object Invoke(IMethodInvocation invocation)
        {
            object returnValue = null;
            try
            {
                returnValue = invocation.Proceed();
            }
            catch (Exception exception)
            {
                var exceptionMessage = new StringBuilder();
                Exception tempException = exception;
                while (tempException != null)
                {
                    exceptionMessage.AppendFormat("{0}({1})|", tempException.Message, tempException.StackTrace);
                    tempException = tempException.InnerException;
                }
                exceptionMessage.AppendFormat("{0}", exception.StackTrace);
                string message =
                    String.Format(
                        "[LandpyStart]Time-[{0}]; Type-[{1}]; Method-[{2}]; Exception-[{3}];[LandpyEnd]",
                        DateTime.Now, invocation.Method.ReflectedType.FullName,
                        invocation.Method.Name, exceptionMessage);
                Log.Write(message);
                throw;
            }
            return returnValue;
        }
    }
}